package com.evil.application.pojo.dto.form.control.save;

import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.fastjson.JSON;
import com.evil.application.pojo.dto.form.control.code.ControlDTO;
import com.evil.application.pojo.entity.ApplicationForm;
import com.evil.application.pojo.entity.ApplicationFormControl;
import com.evil.application.pojo.entity.FormControlOption;
import com.evil.common.core.enums.RCodeEnum;
import com.evil.common.core.exception.BusinessException;
import lombok.Data;
import lombok.EqualsAndHashCode;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 保存控件 用于实时记录参数 实体
 *
 * @author liyang
 * @date 2022-08-08 00:00
 */
@Data
@EqualsAndHashCode(callSuper = true)
public class SaveControlRespDTO extends SaveControlDTO {

    private ApplicationForm form;

    /**
     * 数据库控件map
     */
    private Map<Long, ApplicationFormControl> dbControlMap;

    /**
     * 数据库控件选项map
     */
    private Map<Long, Map<Long, FormControlOption>> dbControlOptionsMap;

    /**
     * 收集所有控件选项列表
     */
    private List<FormControlOption> optionList;

    /**
     * key前端回传控件id（值为负数）；value实际后端入库控件
     */
    private Map<Long, ApplicationFormControl> controlMap;

    /**
     * key前端回传控件field；value实际后端入库控件
     */
    private Map<String, ApplicationFormControl> controlFieldMap;

    /**
     * key控件id；value（key前端回传控件选项id（值为负数）；value实际后端入库控件选项id（值为正数））
     */
    private Map<Long, Map<Long, Long>> controlOptionIdMap;

    public SaveControlRespDTO(ApplicationForm form, Map<Long, ApplicationFormControl> dbControlMap, Map<Long, Map<Long, FormControlOption>> dbControlOptionsMap) {
        this.form = form;
        this.dbControlMap = dbControlMap;
        this.dbControlOptionsMap = dbControlOptionsMap;
        this.optionList = new ArrayList<>();
        this.controlMap = new HashMap<>();
        this.controlFieldMap = new HashMap<>();
        this.controlOptionIdMap = new HashMap<>();
    }

    /**
     * 记录控件 新旧映射id
     *
     * @param controlDTO controlDTO
     * @param control    control
     */
    public void putControl(ControlDTO controlDTO, ApplicationFormControl control) {
        this.controlMap.put(controlDTO.getControlId(), control);
        // 校验控件field不能重复
        if (this.controlFieldMap.containsKey(controlDTO.getControlField())) {
            throw new BusinessException(RCodeEnum.APPLICATION_FORM_CONTROL_FIELD_REPEAT);
        }
        this.controlFieldMap.put(controlDTO.getControlField(), control);
    }

    /**
     * 记录控件 新旧映射选项id
     *
     * @param controlId   控件id
     * @param oldOptionId 旧选项id
     * @param newOptionId 新选项id
     */
    public void putControlOptionId(Long controlId, Long oldOptionId, Long newOptionId) {
        Map<Long, Long> optionIdMap = this.getOptionIdMapByControlId(controlId);
        optionIdMap.put(oldOptionId, newOptionId);
        this.controlOptionIdMap.put(controlId, optionIdMap);
    }

    /**
     * 根据field 获取 控件
     *
     * @param controlField controlField
     * @return ApplicationFormControl
     */
    public ApplicationFormControl getControlByField(String controlField) {
        if (!controlFieldMap.containsKey(controlField)) {
            throw new BusinessException(RCodeEnum.ERROR_PARAMETER, "控件field不存在");
        }
        return this.controlFieldMap.get(controlField);
    }

    /**
     * 控件 新旧映射选项id
     *
     * @param controlId controlId
     * @return Map
     */
    public Map<Long, Long> getOptionIdMapByControlId(Long controlId) {
        return this.controlOptionIdMap.getOrDefault(controlId, new HashMap<>());
    }

    /**
     * 获取新选项id
     *
     * @param controlId   controlId
     * @param oldOptionId oldOptionId
     * @return Long
     */
    public Long getNewOptionId(Long controlId, Long oldOptionId) {
        Map<Long, Long> optionIdMap = this.getOptionIdMapByControlId(controlId);
        if (!optionIdMap.containsKey(oldOptionId)) {
            throw new BusinessException(RCodeEnum.ERROR_PARAMETER, "表格默认数据选项不存在");
        }
        return optionIdMap.get(oldOptionId);
    }

    /**
     * 获取 控件ids
     *
     * @return List
     */
    public List<Long> getControlIds() {
        return controlMap.values().stream().map(ApplicationFormControl::getControlId).collect(Collectors.toList());
    }

    /**
     * 处理 逻辑表单
     *
     * @return List
     */
    public List<FormControlOption> handleLinkControlOptions() {
        List<FormControlOption> options = new ArrayList<>();
        // 遍历optionList，替换
        this.optionList.forEach(option -> {
            List<Long> linkControlIds = JSON.parseArray(option.getLinkControlIds(), Long.class);
            if (CollectionUtil.isNotEmpty(linkControlIds)) {
                // 替换
                linkControlIds = linkControlIds.stream()
                        .filter(this.controlMap::containsKey)
                        .map(c -> this.controlMap.get(c).getControlId())
                        .collect(Collectors.toList());
                option.setLinkControlIds(JSON.toJSONString(linkControlIds));
                options.add(option);
            }
        });
        return options;
    }
}
